import { _decorator, Component, Node, Vec3, v3, MeshRenderer, BatchingUtility } from 'cc';
import { GlobalConfig } from '../../../Init/Config/GlobalConfig';
import { GlobalTmpData } from '../../../Init/Config/GlobalTmpData';
import { EventTypes } from '../../../Init/Managers/EventTypes';
import { LevelDataTmp } from '../../../Init/SystemStorage/StorageTemp';
import { clog } from '../../../Init/Tools/ColorLog';
import GlobalPool from '../../../Init/Tools/GlobalPool';
import { BasicLayer } from '../Common/Basic/BasicLayer';
import { MappingAwardBox } from './MappingAwardBox';
import { MappingAwardKey } from './MappingAwardKey';
import { MappingObj } from './MappingObj';
const { ccclass, property } = _decorator;

@ccclass('ModelsLayer')
export class ModelsLayer extends BasicLayer {
    mappingRecs: { [uuid: string]: MappingObj } = {};
    createRecs: { [matName: string]: { isCreate: boolean, node: Node, data: { p: Vec3, s: Vec3, r: Vec3 } }[] } = {}
    _isCreateFinish = false;

    // #region -------------------------------层级生命周期------------
    /**初始化 只执行一次*/
    protected init() {

    };
    /**注册通过自定义事件管理器管理的事件  */
    protected onEvents() {
        this.on(EventTypes.Mapping3DEvents.SetAwards, this.onSetAwards, this);
    };
    /**设置状态、数据等, */
    public setData(d: LevelDataTmp) {

        for (const key in d.models) {
            if (!this.createRecs[key]) {
                this.createRecs[key] = [];
            }
            const arr = d.models[key];
            arr.forEach(e => {
                this.createRecs[key].push({ isCreate: false, data: e, node: null });
            });
        }
        //从小到大排序
        for (const key in this.createRecs) {
            // console.log('$ '+key)    
            this.createRecs[key].sort((a, b) => a.data.p.z - b.data.p.z);
        }

        //显示终点
        this.showEndArea3D(d.endArea.p);
    };

    /**重置状态、数据等，子类实现 ,注销事件*/
    public reset() {
        this._isCreateFinish = false;
        this.createRecs = {};
        this.mappingRecs = {};
        GlobalPool.putAllChildren(this.node);
    }
    public customUpdate(dt: number) {
        this.delayShow(dt);
        this.updateMappingRecs(dt);
    }
    public customLateUpdate(dt: number) {

    }

    // #endregion

    //#region ---------------------私有---------------

    //延迟显示
    private delayShow(dt) {

        if (!this._isCreateFinish) {
            let n = 0;
            let max = 50;
            for (const key in this.createRecs) {
                const arr = this.createRecs[key];
                if (n > max) break;

                for (let i = 0; i < arr.length; i++) {
                    const e = arr[i];
                    if (!e.isCreate) {
                        e.node = this.createrModle(key, e.data);
                        e.isCreate = true;
                        n++;
                    }
                    if (n > max) break;
                }
            }
            this._isCreateFinish = n == 0;
        }

        //分段显示
        const curZ = GlobalTmpData.Player.wpos3D.z;
        for (const key in this.createRecs) {
            const arr = this.createRecs[key];
            for (let i = 0; i < arr.length; i++) {
                const e = arr[i];
                if (e.node && e.node.name != 'road') {
                    let z = e.data.p.z;
                    e.node.active = (z < curZ + 50 && z > curZ - 30) || z > 0 && curZ > -30;
                }
            }
        }

    }

    //创建对应的显示模型
    private createrModle(n: string, d: { p: Vec3, s: Vec3, r: Vec3 }) {
        let e = GlobalPool.get(n);
        if (!e) {
            clog.warn(n + ' 预制体不存在');
            return;
        }
        e.setPosition(d.p);
        e.setScale(d.s);
        e.eulerAngles = d.r;
        e.parent = this.node;
        return e;
    }

    //显示终点模型
    private showEndArea3D(p: Vec3) {
        let e = GlobalPool.get('endArea3d');
        e.setPosition(v3(p.x, 0, -p.y).multiplyScalar(GlobalConfig.Scale2DTo3D));
        e.parent = this.node;
    }

    //#endregion

    //#region ---------------------事件---------------
    //
    protected onSetAwards(d: { name: string, p: Vec3, data: { node: Node } }) {
        let e = GlobalPool.get(d.name,);
        let cmp: MappingObj = null;
        e.parent = this.node;
        switch (d.name) {
            case 'awardBox3d':
                cmp = new MappingAwardBox(e, d.data);
                break;
            case 'awardKey3d':
                cmp = new MappingAwardKey(e, d.data);
                break;
            default:
                break;
        }

        cmp.init();
        this.mappingRecs[e.uuid] = cmp;
    }

    //更新
    protected updateMappingRecs(dt) {
        for (const key in this.mappingRecs) {
            const e = this.mappingRecs[key];
            if (e && e.node) {
                e.update(dt);
            } else {
                delete this.mappingRecs[key];
            }
        }
    }

    //#endregion

    //#endregion
}

